#pragma once

#include <iostream>
#include <string>
#include <functional>
#include "InetAddr.hpp"

#include <fcntl.h>

class Reactor;

using func_t  = std::function<std::string(std::string&)>;

class Connection
{
public:
    Connection(int sockfd = -1)
        :_sockfd(sockfd)
    {
    }
    virtual void Reader()
    {}    
    virtual void Sender(std::string&out) 
    {}
    virtual void Exceptor() 
    {}
    void SetNonBlock(int socketfd) 
    {
        int fd = ::fcntl(socketfd,F_GETFL);
        if (fd < 0)
        {
            perror("fcntl error");
            return ;
        }
        ::fcntl(socketfd,F_SETFL,fd | O_NONBLOCK);
    }
    std::string& GetInbuffer() {return _rbuffer;}
    std::string& GetOutbuffer() {return _wbuffer;}

    void RegisterHandler(func_t handler)
    {
        _handler = handler;
    }
    bool IsOutBufferempty() { return _wbuffer.empty();}
    void AppendReadBuffer(const std::string& in) 
    {
        _rbuffer += in;
    }
    void AppendOutBuffer(const std::string& out)
    {
        _wbuffer += out;
    }
    void Discard(int n )
    {
        _wbuffer.erase(0,n);
    }
    void SetOwner(Reactor* owner) { _owner = owner;}
    Reactor* GetOwner() { return _owner;}
    void SetConnectionFd(int fd) {_sockfd = fd;}
    void SetPeerInfo(const InetAddr &peer) { _peer = peer; }
    void Setevents(uint32_t events) { _events = events; }
    uint32_t Getevents() { return _events; }
    int Fd() { return _sockfd; }
    void Close() {::close(_sockfd);}
    virtual ~Connection() {}
protected:
    int _sockfd;
    std::string _rbuffer;
    std::string _wbuffer;
    uint32_t _events;
    InetAddr _peer;
    func_t _handler;
    Reactor *_owner; // 指向自己属于哪一个epoll服务
};